﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using MapSurface.Engine;
using System.Windows.Markup;
using System.Diagnostics;
using MapSurface.MapSurfaceGUI;
using MapSurface.WidgetSurface;
namespace MapSurface
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {
        #region Properties
        private string _dir = @"C:\Users\Nepthys\Documents\Andre\workspace1\mapgui\models\ui";
        private string dllDir = "";
        public UIModelLoader modelLoader = null;
        public UIElement uiRoot = null;
        public ScatterViewItem rootSc = null;
        public Canvas MainCanvas=null;
        public Object selectElement = null;
        public String fileSelected = null;
        public UIElementMoveHandler moveHandler=null;
        #endregion
        
        #region InitializeComponents
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SurfaceWindow1()
        {
            InitializeComponent();
            // Add handlers for Application activation events
            AddActivationHandlers();
            if (IntPtr.Size == 4)
                dllDir = @"..\..\Assembly";
            else if (IntPtr.Size == 8) 
                dllDir=@".\Assembly";
            loadModel(_dir);
            modelLoader = new UIModelLoader();
            moveHandler = new UIElementMoveHandler(this);
        }


        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here
        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }
        #endregion
 
        #region ModelsLoader
        private void SurfaceListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            fileSelected = ((SurfaceListBoxItem)((SurfaceListBox)sender).SelectedItem).ContentStringFormat;
            if (modelLoader == null)
                modelLoader = new UIModelLoader(fileSelected, "",dllDir);
            else
                modelLoader.setLoader(fileSelected,dllDir);
            //modelLoader.Assembly.ContactEventsHandler = new Dictionary<string, Delegate>();
            //modelLoader.Assembly.ContactEventsHandler.Add("ContactDown", new Microsoft.Surface.Presentation.ContactEventHandler(this.elementContactDown));

            DesignSpace.Children.Add( (UIElement)modelLoader.process(this));
            EditElements.IsEnabled = true;
        }
        private void reloadUIElement(Object ui)
        {
            if (DesignSpace.Children.Contains(uiRoot))
            {
                modelLoader.Assembly.removeVisualChid(DesignSpace, uiRoot);
                DesignSpace.Children.Remove(uiRoot);
                
            }
            else
                DesignSpace.Children.Add((UIElement)ui);
            if (ui != null)
            {
                
                labelTypeValue.Content = "";
                labelNameValue.Content = "";
                labelHValue.Content = "";
                labelWValue.Content = "";
                labelBValue.Content = "";
                DeleteElement.IsEnabled = false;
                Deselect.IsEnabled = false;
                selectElement = null;
            }
        }
        private void loadModel(string dir)
        {
            List<SurfaceListBoxItem> li = UIModelLoader.loadFile(dir);
            foreach (SurfaceListBoxItem i in li)
                ExplorerList.Items.Add(i);
        }
        #endregion

        #region Handler
        private void SurfaceButton_Click(object sender, RoutedEventArgs e)
        {
            labelTypeValue.Content = "";
            labelNameValue.Content = "";
            labelHValue.Content = "";
            labelWValue.Content = "";
            labelBValue.Content = "";
            DeleteElement.IsEnabled = false;
            selectElement = null;
            Deselect.IsEnabled = false;
            disableSizeButton();

        }
        private void Save_Code(object sender, RoutedEventArgs e)
        {
            String file = "./code2.xaml";
            modelLoader.XamlObject.concretise(file);
        }
        private void elementContactDown(object sender, ContactEventArgs e)
        {

            if (selectElement == null)
            {
                selectUIElement(sender);
            }
        }
        private void elementMouseDown(object sender, RoutedEventArgs e)
        {

            if (selectElement == null)
            {
                selectUIElement(sender);
            }
        }
        public void handler(object sender, EventArgs e)
        {
            if (selectElement == null)
            {
                selectUIElement(sender);
            }
        }
        #endregion

        #region UIOperations
        public void selectUIElement(object sender)
        {
            if (sender!=null)
            {
                selectElement = sender;
                Deselect.IsEnabled = true;
                displayPropertie(sender);
                enabledSizeButton();
                bool value=true;
                modelLoader.Assembly.setAttribute(ref selectElement, "Focusable",value);

                Brush b = Brushes.Black;
                modelLoader.Assembly.setAttribute(ref selectElement, "Foreground", b);
 /*               Object element=(Object)uiRoot;
                if (modelLoader.Assembly.selectUIElement(ref element, selectElement) == 0)
                {
                    DesignSpace = (Canvas)modelLoader.Assembly.removeVisualChid(DesignSpace, selectElement);
                    Border b = modelLoader.Assembly.setBorder((System.Windows.UIElement)selectElement);
                    modelLoader.Assembly.setHandler(b, "ContactDown", this, "Size_HPlus");
                    //uiRoot = b;
                    //DesignSpace.Children.Add(b);
                    modelLoader.Assembly.setVisualChild(DesignSpace,b);
                }-*/
                //uiRoot =(UIElement) element;
                //DesignSpace.UpdateLayout();
            }
        }

        private void enabledSizeButton()
        {
            SizeHPlus.IsEnabled = true;
            SizeWPlus.IsEnabled = true;
            SizeHMinus.IsEnabled = true;
            SizeWMinus.IsEnabled = true;

        }
        private void disableSizeButton()
        {
            SizeHPlus.IsEnabled = false;
            SizeWPlus.IsEnabled = false;
            SizeHMinus.IsEnabled = false;
            SizeWMinus.IsEnabled = false;

        }

        private void displayPropertie(object uiElement)
        {
            labelTypeValue.Content = uiElement.GetType().Name;
            labelNameValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Name");
            if (string.Compare(labelNameValue.Content.ToString(), "") == 0)
                labelNameValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Content"); //DesiredSize
            Object size = modelLoader.Assembly.getAttribute(uiElement, "RenderSize");
            if (size != null)
            {
                string[] s = size.ToString().Split(';');
                labelWValue.Content= s[0];
                labelHValue.Content = s[1];
            }
            labelBValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Background");
            if (string.Compare(labelBValue.Content.ToString(), "") == 0)
                labelBValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Fill");
            DeleteElement.IsEnabled = true;
        }

        private void RemoveElement(object sender, RoutedEventArgs e)
        {
            Object newRoot=uiRoot;
            UpdateUIModel updateModel = new UpdateUIModel(fileSelected);
            String id=updateModel.deleteUINode(modelLoader.Assembly.getAttribute(selectElement, "Name"));
            reloadUIElement(modelLoader.reprocess(id));
        }

        private void EditElement(object sender, RoutedEventArgs e)
        {
            Object newRoot = uiRoot;
            modelLoader.processEditMode(ref newRoot, moveHandler);
            uiRoot = (UIElement)newRoot;
        }
        private void Size_WPlus(object sender, RoutedEventArgs e)
        {

            Double w = Double.Parse(labelWValue.Content.ToString());
            Double h = Double.Parse(labelHValue.Content.ToString());
            w++;
            Size s= new Size(w,h);
            modelLoader.Assembly.setAttribute(ref selectElement, "RenderSize", s);
            displayPropertie(selectElement);
            DesignSpace.UpdateLayout();
            ((UIElement)selectElement).UpdateLayout();

        }
        private void Size_WMinus(object sender, RoutedEventArgs e)
        {
            Double w = Double.Parse(labelWValue.Content.ToString());
            Double h = Double.Parse(labelHValue.Content.ToString());
            w--;
            Size s = new Size(w, h);
            modelLoader.Assembly.setAttribute( ref selectElement, "RenderSize", s);
            displayPropertie(selectElement);

        }
        private void Size_HPlus(object sender, RoutedEventArgs e)
        {
            Double w = Double.Parse(labelWValue.Content.ToString());
            Double h = Double.Parse(labelHValue.Content.ToString());
            h++;
            Size s = new Size(w, h);
            modelLoader.Assembly.setAttribute(ref selectElement, "RenderSize", s);
            displayPropertie(selectElement);

        }
        private void Size_HMinus(object sender, RoutedEventArgs e)
        {
            Double w = Double.Parse(labelWValue.Content.ToString());
            Double h = Double.Parse(labelHValue.Content.ToString());
            h--;
            Size s = new Size(w, h);
            modelLoader.Assembly.setAttribute(ref selectElement, "RenderSize", s);
            displayPropertie(selectElement);

        }

        #endregion
    }
   }